package com.pap.gateway.config;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pap.gateway.dynamicrouter.router.DynamicRouteServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 *  网关动态路由
 *
 *  [
 *        {
 * 		"filters": [
 *            {
 * 				"name": "RequestRecord"
 *            }
 * 		],
 * 		"id": "pap-uua-get",
 * 		"order": 1,
 * 		"predicates": [{
 * 			"args": {
 * 				"pathPattern": "/uua/**"
 *            },
 * 			"name": "Path"
 *        },{
 * 			"args": {
 * 				"Method": "GET"
 *            },
 * 			"name": "Method"
 *        }],
 * 		"uri": "lb://pap-uua"
 *    },
 *    {
 * 		"filters": [
 *            {
 * 				"name": "RequestRecord"
 *            }
 * 		],
 * 		"id": "pap-uua-post",
 * 		"order": 1,
 * 		"predicates": [{
 * 			"args": {
 * 				"pathPattern": "/uua/**"
 *            },
 * 			"name": "Path"
 *        },{
 * 			"args": {
 * 				"Method": "POST"
 *            },
 * 			"name": "Method"
 *        }],
 * 		"uri": "lb://pap-uua"
 *    }
 * ]
 *
 *  注： 此功能用于结合 nacos 进行 动态路由 的下发监听，关联 DynamicRouteServiceImpl 类文件进行 路由刷新
 *
 *  同时注意 RequestRecordGatewayFilterFactory 类文件的定义，用于结合上述 JSON 格式段 的 filters 配置，注意定义并非驼峰式定义，而是大写。
 */
@Component
public class DynamicGateWayRouterPropertiesByNacos {

    private static Logger logger  =  LoggerFactory.getLogger(DynamicGateWayRouterPropertiesByNacos.class);

    @Value(value = "${spring.cloud.nacos.config.server-addr}")
    private String papNacosServerAdd;

    @Value(value = "${spring.cloud.nacos.config.namespace}")
    private String papNacosNameSpace;

    @Autowired
    private DynamicRouteServiceImpl dynamicRouteService;

    /**
     * 监听Nacos Server下发的动态路由配置
     */
    @PostConstruct
    public void dynamicRouteByNacosListener (){
        try {
            Properties gatewayProperties = new Properties();
            gatewayProperties.put(PropertyKeyConst.SERVER_ADDR, papNacosServerAdd);
            gatewayProperties.put(PropertyKeyConst.NAMESPACE, papNacosNameSpace);
            ConfigService configService = NacosFactory.createConfigService(gatewayProperties);
            configService.addListener("com.pap.gateway.config.router", "GATEWAY_GROUP", new Listener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    try {
                        // TODO 注意这里根据监听到的数据变化，进行 网关路由 控制
                        ObjectMapper mapper = new ObjectMapper();
                        List<RouteDefinition> definitionList = mapper.readValue(configInfo, new TypeReference<List<RouteDefinition>>() {});
                        dynamicRouteService.update(definitionList);
                    } catch (IOException e) {
                        logger.error("DynamicGateWayRouterPropertiesByNacos.dynamicRouteByNacosListener.路由下发更新: [{}]", e.getMessage());
                    }
                }
                @Override
                public Executor getExecutor() {
                    return null;
                }
            });
        } catch (NacosException e) {
            e.printStackTrace();
        }
    }
}
